package org.luxor.commons.log.filter;

import org.luxor.commons.core.utils.HttpContextUtils;
import org.luxor.commons.core.utils.Jackson2Utils;
import org.luxor.commons.core.utils.StringUtils;
import org.luxor.commons.log.component.HttpRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.ServerHttpResponse;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 跟踪日志
 *
 * @author Mr.yan @date 2019/9/21
 */
public class RestLog {
    private static final Logger logger = LoggerFactory.getLogger(RestLog.class);
    private static final ThreadLocal<Long> startTime = new ThreadLocal<Long>();

    /**
     * 启用DEBUG
     */
    public synchronized static boolean isDebugEnabled() {
        return logger.isDebugEnabled();
    }

    /**
     * 打印请求
     */
    public synchronized static void logRequest(HttpRequestWrapper request) {
        startTime.set(System.currentTimeMillis());
        if (requiresLog(request)) {
            StringBuilder cookieBuilders = new StringBuilder();
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (int i = 0; i < cookies.length; i++) {
                    cookieBuilders.append(cookies[i].getName());
                    cookieBuilders.append("=");
                    cookieBuilders.append(cookies[i].getValue());
                    if (i < cookies.length - 1) {
                        cookieBuilders.append("; ");
                    }
                }
            }
            Map logMap = new HashMap(8);
            logMap.put("Method", request.getMethod());
            logMap.put("Path", request.getServletPath());
            logMap.put("Host", HttpContextUtils.getRemoteAddr(request));
            logMap.put("Content-Length", request.getContentLength());
            logMap.put("Cookies", cookieBuilders.toString());
            logMap.put("Referer", request.getHeader("Referer"));
            logMap.put("Content-Type", StringUtils.toString(request.getHeader("Content-Type")));
            logMap.put("User-Agent", request.getHeader("User-Agent"));
            logger.debug("接收请求:");
            logger.debug(Jackson2Utils.toJsonPretty(logMap));
            logger.debug("接收内容:");
            logger.debug(request.toString());
        }
    }

    /**
     * 需要打印日志吗？
     */
    private static boolean requiresLog(HttpServletRequest request) {
        String path = request.getServletPath();
        if (path.contains("/swagger") || path.contains("/druid") || "/info".equals(path) || "/health".equals(path)) {
            return false;
        }
        if (request.getContentType() == null || request.getContentType().startsWith("multipart") || request.getContentLength() > 1000000) {
            return false;
        }
        return true;
    }

    /**
     * 打印返回结果
     */
    public synchronized static void logResponse(ServerHttpResponse response, Map result) {
        Long begin = startTime.get();
        if (begin != null) {
            long timeContinuous = System.currentTimeMillis() - startTime.get();
            logger.debug("执行{}毫秒，返回结果:\n {}", timeContinuous, Jackson2Utils.toJsonPretty(result));
        }
    }

    /**
     * 打印返回结果
     */
    public synchronized static void logResponse(HttpServletResponse response, Map result) {
        Long begin = startTime.get();
        if (begin != null) {
            long timeContinuous = System.currentTimeMillis() - startTime.get();
            logger.debug("执行{}毫秒，返回结果:\n {}", timeContinuous, Jackson2Utils.toJsonPretty(result));
        }
    }

}
